#ifndef H_C_WHEEL_TIMERMGR_H
#define	H_C_WHEEL_TIMERMGR_H

#include "../typedefine.h"
#ifdef _USING_CLI
#endif
#include "../objpool.h"
#include "STimerUID.h"
#include "TimerDelegate.h"

#ifndef _USING_CLI
#define TIMER_LIST_COUNT 5
#define TIMER_CYCLE 7
#endif

namespace TB
{
	QCLASS CTimer;
	QCLASS CExecTimerInfoList;
	QSTRUCT STimerInfo;

	QDLL_EXPORT QCLASS CWheelTimerMgr
	{
		NON_COPYABLE(CWheelTimerMgr)
	public:
		CWheelTimerMgr(volatile UINT64* pqwCurTime = nullptr);
#ifndef _USING_CLI
		~CWheelTimerMgr();
#endif
		inline void SetCurTimeOffset(UINT64 qwMilliSeconds) { m_qwCurTimeOffset = qwMilliSeconds; }
		inline UINT64 GetCurTime() const { return *m_pqwCurTime + m_qwCurTimeOffset; }
		UINT32 Poll(UINT64 qwDeltaMilliSeconds);
        STimerUID StartTimer(UINT64 dwMilliSeconds, CONST_PTR_OR_REF(DOnTimer) ronTimer, bool bAutoFix = false);
        STimerUID StartTimer(UINT64 dwMilliSeconds, UINT32 dwCount, CONST_PTR_OR_REF(DOnTimer) ronTimer, bool bAutoFix = false);
        STimerUID StartTimer(UINT64 dwMilliSeconds, UINT32 dwCount, UINT64 dwFirstTimeoutMilliSeconds, CONST_PTR_OR_REF(DOnTimer) ronTimer, bool bAutoFix = false);
        BOOLN IsTimerRunning(CONST_REF(STimerUID) rsTimerUID) QCONST_FUNC;
        void StopTimer(CONST_REF(STimerUID) rsTimerUID);
		UINT64 GetNextPollTime() const;
		inline UINT32 GetMaxCountPerPoll() QCONST_FUNC { return m_dwMaxCountPerPoll; }
		inline void SetMaxCountPerPoll(UINT32 dwMaxCountPerPoll) { m_dwMaxCountPerPoll = dwMaxCountPerPoll; }

	private:
		CUniquePtr(CTimer) _NewTimer(UINT16 wObjType);
		void _AddTimer(CONST_REF(STimerUID) rsTimerUID,	UINT64 qwExecTime);
		UINT32 _ExecTimer(UINT32 dwMaxCount);
		void _Tick(UINT16 wLevel);
		void _AddTimerInfo(UINT16 wLevel, REF(STimerInfo) rsInfo);

	private:
#ifdef _USING_CLI
		static UINT32 TIMER_LIST_COUNT = 5;
		static array<UINT64>^ m_aTimeOffsets = gcnew array<UINT32>(TIMER_LIST_COUNT);
#else
		static UINT64 m_aTimeOffsets[TIMER_LIST_COUNT];
#endif
        PTR(CObjectResMgr<PTR_OR_VAL(CTimer)>) m_poTimerMgr = NULL_PTR;
		UINT64 m_qwCurTimeOffset = 0;
		UINT64 m_qwCurTime = 0;
		volatile UINT64* m_pqwCurTime = &m_qwCurTime;
#ifdef _USING_CLI
		array<CExecTimerInfoList^>^ m_aTimers;
#else
		CExecTimerInfoList* m_aTimers[TIMER_LIST_COUNT];
#endif
		PTR(CVector(STimerInfo)) m_poExtTimers = NULL_PTR;
		UINT32 m_dwMaxCountPerPoll = 100;
	};
};

#endif

